﻿using Sustainalytics.Claims;
using Sustainalytics.Entities;
using Sustainalytics.ScreeningTool.Service.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace Sustainalytics.ScreeningTool.Service
{
    public class CriteriaLevel1Dto
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
        public bool IsEnabled { get; private set; }
        public List<object> ChildItems { get; set; }

        private CriteriaLevel1Dto()
        {
        }

        public static CriteriaLevel1Dto CreateComplete(CriteriaLevel1 criteriaLevel1, List<CriteriaLevel2> criteriaLevel2List, List<BaseCriteria> baseCriteria, ApiController controller, IClaimsChecker _claimsChecker)
        {
            if (criteriaLevel1 == null)
                throw new ArgumentNullException("CriteriaLevel1", "CriteriaLevel1 cannot be null.");

            if (baseCriteria.Any(c => c.CriteriaType == CriteriaTypeEnum.CriteriaType4))
                baseCriteria = baseCriteria.OrderBy(c => c.Order).ToList();

            return new CriteriaLevel1Dto()
            {
                Id = criteriaLevel1.Id,
                Name = criteriaLevel1.Name,
                ChildItems = criteriaLevel2List.ConvertAll<object>(cr2 => CriteriaLevel2Dto.CreateComplete(cr2, baseCriteria.Where(bc => bc.CriteriaLevel2Id == cr2.Id).ToList(), ValidateCriteriaLevel2(controller, cr2.ShortName, criteriaLevel1.ShortName, _claimsChecker), controller, _claimsChecker)),
                IsEnabled = ValidateTabs(controller, criteriaLevel1.ShortName, criteriaLevel2List.Select(cr => cr.ShortName).ToList(), _claimsChecker) && criteriaLevel2List.Count > 0
            };
        }

        public static object CreateWithNameId(CriteriaLevel1 criteriaLevel1, ApiController controller, IClaimsChecker _claimsChecker)
        {
            if (criteriaLevel1 == null)
                throw new ArgumentNullException("CriteriaLevel1", "CriteriaLevel1 cannot be null.");

            return new
            {
                Id = criteriaLevel1.Id,
                Name = criteriaLevel1.Name,
                IsEnabled = ValidateTabs(controller, criteriaLevel1.ShortName, null, _claimsChecker)
            };
        }

        private static bool ValidateTabs(ApiController controller, string shortName, List<string> childShortNames, IClaimsChecker _claimsChecker)
        {
            if (_claimsChecker.ValidateCriteria(controller, "fullaccess", ""))
                return true;

            if (_claimsChecker.ValidateCriteria(controller, shortName, ""))
                return true;

            if (childShortNames != null && childShortNames.Count > 0)
            {
                foreach (var ch in childShortNames)
                {
                    if (_claimsChecker.ValidateCriteria(controller, ch, ""))
                        return true;
                }
            }

            return false;
        }

        private static bool ValidateCriteriaLevel2(ApiController controller, string shortName, string parentShortName, IClaimsChecker _claimsChecker)
        {
            if (_claimsChecker.ValidateCriteria(controller, shortName, ""))
                return true;

            if (_claimsChecker.ValidateCriteria(controller, parentShortName, ""))
                return true;

            if (_claimsChecker.ValidateCriteria(controller, "fullaccess", ""))
                return true;

            return false;
        }
    }
}
